/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.raflik.queryxml.ui.tasks;

import pl.raflik.queryxml.ui.tasks.io.RunQueryInput;
import pl.raflik.queryxml.ui.tasks.io.RunQueryOutput;
import pl.raflik.queryxml.ui.tasks.io.CommonQueryOutput;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.openide.filesystems.FileObject;
import org.w3c.dom.Document;
import pl.raflik.queryxml.lib.io.FileOp;
import pl.raflik.queryxml.serializer.QueryResultSerializeException;
import pl.raflik.queryxml.serializer.QueryResultSerializer;
import pl.raflik.queryxml.ui.UITransfer;

/**
 *
 * @author raflik
 */
public class RunQueryThread extends CommonQueryThread<RunQueryInput, RunQueryOutput> {

    private static final String OUTPUT_NAME_PREFIX = "output";

    public RunQueryThread(UITransfer<RunQueryInput, RunQueryOutput> transfer, Map<String, Document> cache) {
        super(transfer, cache);

    }

    @Override
    protected RunQueryOutput performOperation(RunQueryInput input) {
        CommonQueryOutput output = performCommonOperation(input);

        QueryResultCode currResult = output.getResultCode();
        if (currResult.isError()) {
            return new RunQueryOutput(currResult);
        }

        final List<?> queryResult = output.getQueryResult();
        final List<Object> extractedResult = new ArrayList<Object>();
        for (Object resultEl : queryResult) {
            if (resultEl != null) {
                extractedResult.add(resultEl);
            }
        }
        if (extractedResult.size() == 0) {
            return new RunQueryOutput(QueryResultCode.RESULT_EMPTY);
        }


        final QueryResultSerializer serializer = input.getQueryResultSerializer();
        final String ext = serializer.getExtension();

        final String suffix = ext == null || ext.length() == 0 ? "" : "." + ext;
        FileObject destFO = FileOp.createTempFile(OUTPUT_NAME_PREFIX, suffix);
        if (destFO == null) {
            return new RunQueryOutput(QueryResultCode.TEMP_FILE_CREATE_FAILED);
        }
        OutputStream os = null;

        try {
            os = destFO.getOutputStream();
            if (os == null) {
                return new RunQueryOutput(QueryResultCode.TEMP_FILE_WRITE_FAILED);
            }
            try {
                serializer.serialize(queryResult, os, null);
            } catch (QueryResultSerializeException e) {
                return new RunQueryOutput(QueryResultCode.SERIALIZATION_FAILED);
            } finally {
                try {
                    os.close();
                } catch (IOException e) {
                }
            }
        } catch (IOException e) {
            return new RunQueryOutput(QueryResultCode.TEMP_FILE_WRITE_FAILED);
        }

        return new RunQueryOutput(QueryResultCode.QUERY_OK, input.getQuery(), destFO);
    }
}
